package com.example.librarymanagement.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.example.librarymanagement.dto.menu.MenuDto;
import com.example.librarymanagement.entity.Menu;
import com.example.librarymanagement.dao.MenuMapper;
import com.example.librarymanagement.entity.RoleMenu;
import com.example.librarymanagement.entity.User;
import com.example.librarymanagement.service.IMenuService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.librarymanagement.service.IRoleMenuService;
import com.example.librarymanagement.service.IUserService;
import com.example.librarymanagement.vo.MenuNavVo;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.*;

/**
 * @author fgba
 * @since 2021-05-08
 */
@Service
public class MenuServiceImpl extends ServiceImpl<MenuMapper, Menu> implements IMenuService {

    @Resource
    private IUserService userService;

    @Resource
    private IRoleMenuService roleMenuService;

    @Override
    public List<MenuNavVo> getCurrentUserNav() {

        String username = (String) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        User user = userService.getUserByUsername(username);
        List<Integer> menuIds = baseMapper.getNavMenuIds(user.getId());
        List<Menu> menus = listByIds(menuIds);
        List<Menu> treeList = buildTreeList(menus);

        return convert(treeList);
    }

    @Override
    public List<Menu> getMenuTreeList() {
        return buildTreeList(list(new QueryWrapper<Menu>().orderByAsc("order_num")));
    }

    @Override
    public Boolean addOrUpdMenu(MenuDto menuDto) {
        Menu menu = new Menu();
        menuDto.convertToEntity(menu);
        if (menu.getId() != null) {
            menu.setUpdated(LocalDateTime.now());
            userService.clearUserAuthorityInfoByMenuId(menu.getId());
            return updateById(menu);
        }
        menu.setCreated(LocalDateTime.now());
        return save(menu);
    }

    @Override
    public Boolean delMenu(Integer id) {
        userService.clearUserAuthorityInfoByMenuId(id);
        removeById(id);
        roleMenuService.remove(new QueryWrapper<RoleMenu>().eq("menu_id", id));
        return true;
    }

    /**
     * 根据菜单列表构造树型菜单列表
     *
     * @param menus 菜单列表
     * @return 树型菜单列表
     */
    private List<Menu> buildTreeList(List<Menu> menus) {
        List<Menu> treeList = new ArrayList<>();

        for (Menu menu : menus) {
            for (Menu m : menus) {
                if (m.getParentId().equals(menu.getId())) {
                    menu.getChildren().add(m);
                }
            }
            if (menu.getParentId() == 0) {
                treeList.add(menu);
            }
        }
        return treeList;
    }

    /**
     * 将菜单列表转换为MenuNavVo树形列表
     *
     * @param menus 菜单列表
     * @return MenuNavVo树形列表
     */
    private List<MenuNavVo> convert(List<Menu> menus) {
        List<MenuNavVo> finalMenuNavVoList = new ArrayList<>();
        for (Menu menu : menus) {
            MenuNavVo menuNavVo = new MenuNavVo();
            menuNavVo.setName(menu.getPerms());
            menuNavVo.setComponent(menu.getComponent());
            menuNavVo.setIcon(menu.getIcon());
            menuNavVo.setId(menu.getId());
            menuNavVo.setTitle(menu.getName());
            menuNavVo.setPath(menu.getPath());
            menuNavVo.setType(menu.getType());
            if (menu.getChildren().size() > 0) {
                menuNavVo.setChildren(convert(menu.getChildren()));
            } else {
                menuNavVo.setChildren(null);
            }
            finalMenuNavVoList.add(menuNavVo);
        }

        return finalMenuNavVoList;
    }
}
